package myweb

import (
	"fmt"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
	"github.com/spf13/viper"
	"github.com/topfreegames/pitaya/v3/pkg/component"
	"github.com/topfreegames/pitaya/v3/pkg/logger"
	"google.golang.org/protobuf/proto"
	"server/modules/account"
	"server/pb/pb_common"
	"server/pb/pb_http"
)

type MyWeb struct {
	component.Base
}

func NewMyWeb() *MyWeb {
	return &MyWeb{}
}

func (this *MyWeb) Init() {
	this.Start()
}

func (this *MyWeb) Start() {
	app := fiber.New()
	app.Use(cors.New(cors.Config{
		AllowOrigins: "*",
		AllowHeaders: "Origin, Content-Type, Accept",
	}))
	app.Get("/", this.hello)
	app.Get("/ping", this.ping)
	app.Get("/api", this.doapi)
	app.Post("/entry", this.entry)
	app.Post("/register", this.register)
	app.Post("/login", this.login)
	port := viper.GetInt("net.http.port")
	app.Listen(":" + fmt.Sprintf("%d", port))
}

func (this *MyWeb) hello(c *fiber.Ctx) error {
	return c.SendString("Hello, World!")
}
func (this *MyWeb) ping(c *fiber.Ctx) error {
	return c.SendString("pong")
}
func (this *MyWeb) doapi(c *fiber.Ctx) error {
	return c.JSON(c.BaseURL())
}
func (this *MyWeb) entry(c *fiber.Ctx) error {
	//logger := pitaya.GetDefaultLoggerFromCtx(c.Context())
	logger.Log.Info("[entry]:myweb entry,是的,myweb接口调用成功了")
	buf := c.Body()
	req := new(pb_http.ReqEntry)
	if err := proto.Unmarshal(buf, req); err != nil {
		return err
	}
	logger.Log.Info("[entry], req.Secret=%s\n", req.Secret)
	resp := new(pb_http.RespEntry)
	resp.ErrCode = pb_common.ErrorCode_OK
	resp.LoginUrl = fmt.Sprintf("http://%s:%d/login", viper.GetString("net.http.ip"), viper.GetInt("net.http.port"))
	resp.RegisterUrl = fmt.Sprintf("http://%s:%d/register", viper.GetString("net.http.ip"), viper.GetInt("net.http.port"))
	resp.TcpUrl = &pb_http.RespEntry_Addr{
		Host: viper.GetString("net.tcp.ip"),
		Port: int32(viper.GetInt("net.tcp.port")),
	}
	resp.WebSocketUrl = &pb_http.RespEntry_Addr{
		Host: viper.GetString("net.ws.ip"),
		Port: int32(viper.GetInt("net.ws.port")),
	}
	if pbByte, err := proto.Marshal(resp); err == nil {
		logger.Log.Info("[entry] result=%v\n", resp)
		//w.Write(pbByte)
		return c.Send(pbByte)
	}
	return c.SendString("ok")
}

func (this *MyWeb) register(c *fiber.Ctx) error {
	buf := c.Body()
	req := new(pb_http.ReqRegister)
	if err := proto.Unmarshal(buf, req); err != nil {
		return err
	}
	logger.Log.Info("onRegister req=", req)
	if req.Account == "" || req.Password == "" {
		return c.SendString("wrong account or password")
	}
	resp := new(pb_http.RespRegister)
	err := account.GetManager().OnRegister(req.Account, req.Password)
	if err != nil {
		resp.ErrCode = pb_common.ErrorCode_Default
		return err
	}
	resp.ErrCode = pb_common.ErrorCode_OK
	logger.Log.Infof("[register] result=%v\n", resp)
	pbByte, err := proto.Marshal(resp)
	if err != nil {
		logger.Log.Errorf("onRegister resp to byte error, err=", err)
		return err
	}
	//w.Write(pbByte)
	return c.Send(pbByte)
}

func (this *MyWeb) login(c *fiber.Ctx) error {
	buf := c.Body() //.ReadAll(r.Body)
	req := new(pb_http.ReqLogin)
	if err := proto.Unmarshal(buf, req); err != nil {
		return err
	}
	logger.Log.Infoln("onLogin req=", req)
	if req.Account == "" {
		return c.SendString("wrong account")
	}
	resp := new(pb_http.RespLogin)
	//回复客户端
	doResp := func() error {
		logger.Log.Infof("[login] result=%v\n", resp)
		if pbByte, err := proto.Marshal(resp); err == nil {
			//_, _ = w.Write(pbByte)
			return c.Send(pbByte)
		}
		return c.SendString("marshal error")
	}

	if !account.GetManager().HasRegister(req.Account) {
		resp.ErrCode = pb_common.ErrorCode_LoginAccountUnExistent
		return doResp()

	}

	token, err := account.GetManager().DoLogin(req.Account, req.Password)
	if err != nil {
		resp.ErrCode = pb_common.ErrorCode_LoginPasswordError
		resp.Token = err.Error()
	} else {
		resp.ErrCode = pb_common.ErrorCode_OK
		resp.Token = token
	}
	return doResp()
}
